#include <iostream>
#include "utf8_output.h"
#include <iostream>
#include <tuple>
using std::cout;
using std::endl;
template <class... T>
void f(T... args)
{
    cout << sizeof...(args) << endl;
}
// 1、使用模板递归的方式展开
//  没参数 当终止
template <class Head>
void print(Head head)
{
    cout << head << endl;
}
template <class Head, class... Args>
void print(Head head, Args... args)
{
    std::cout << head << " ";
    print(args...);
}

// 2、使用 tuple 实现的打印函数
// 具体位 tuple中有个get<I>这个 然后用这个I逐渐递增
// 基础情况：当索引I等于元组大小时，不执行任何操作
template <std::size_t I = 0, typename Tuple>
typename std::enable_if<I == std::tuple_size<Tuple>::value>::type print_tuple(Tuple t)
{
    // 什么都不做
}

// 递归情况：当索引I小于元组大小时，打印当前索引的元素，并递归调用print_tuple
template <std::size_t I = 0, typename Tuple>
    typename std::enable_if < I<std::tuple_size<Tuple>::value>::type print_tuple(Tuple t)
{
    std::cout << std::get<I>(t) << std::endl;
    print_tuple<I + 1>(t);
}

// 可变参数模板函数，接受任意数量的参数
template <typename... Args>
void print_with_tuple(Args... args)
{
    // 将参数打包成一个元组，并调用print_tuple
    print_tuple(std::make_tuple(args...));
}
// 3使用逗号表达式展开
template <typename T>
void printarg(T value)
{
    cout << value << endl;
}
template <typename... Args>
void expand(Args... args)
{
    int arr[] = {(printarg(args), 0)...}; // cpp11
}
// 4、使用折叠表达式 使用折叠表达式不能改变参数包的展开顺序
template <typename... Args>
void print_with_fold(Args... args)
{
    (..., (printarg(args))); // 左折叠
}
//
// 5、使用模板继承的方式展开
template<typename... Args>
struct print_helper;

// 基础情况：空参数包
template<>
struct print_helper<> {
    static void print() {}
};

// 递归情况：至少有一个参数
template<typename First, typename... Rest>
struct print_helper<First, Rest...> : print_helper<Rest...> {
    static void print(First first, Rest... rest) {
        std::cout << first << std::endl;
        print_helper<Rest...>::print(rest...);
    }
};

template<typename... Args>
void print_with_inheritance(Args... args) {
    print_helper<Args...>::print(args...);
}


int main()
{
    f();                  // 输出: 0
    f(1);                 // 输出: 1
    f(1, 2);              // 输出: 2
    f(1, 2, 3);           // 输出: 3
    f("hello", 42, 3.14); // 输出: 3

    // 测试 print 函数
    print("Hello"); // 单参数测试

    print("C++", 17, "Templates"); // 多参数，不同类型测试

    print(1, 3.14, "Variadic", 'A', true); // 更多不同类型的参数测试

    std::cout << "\n使用 tuple 实现的打印测试：" << std::endl;
    print_with_tuple(1, 2.5, "Hello", true);
    std::cout << "\n使用逗号表达式展开：" << std::endl;
    expand(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    std::cout << "\n使用折叠表达式展开：" << std::endl;
    print_with_fold(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    std::cout << "\n使用模板继承展开：" << std::endl;
    print_with_inheritance(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    return 0;
}